Repository navigation
Recover blocked release PRs with one targeted Fix run - #2021
Conversation
The notes marker is read after the Experiment returns. A PR edit during that yield can name the new content base, so the script tags that head under the old result. Snapshot the marker before the yield and treat Experiment coverage as the base this process measured.
… advice Review of #2021: green CI with mergeability stuck UNKNOWN now stops after the startup grace instead of waiting forever. A closed, retargeted or moved PR, a changed origin, or a stale content base no longer recommends a Fix run. Release check tests use the shared 120-second fixture bound, the base-change Experiment test asserts unconditionally, and the legacy notes refresh is documented.
|
Review run. Pushed fixes to issue-2016 at 63be9d1. Spec axis used the linked closing issues. Review of PR #2021 (issue #2016): release PR recoveryThe review found 8 Standards findings and 3 Spec findings. I fixed 3 confirmed bugs plus 4 of the code-quality findings, and declined the rest. Everything is in one commit, Fixed point: the ref Spec source: linked closing issue #2016 and its Agent Brief, from PR state: open and not draft at every check. Standards (8 findings: 2 P2, 6 P3; no hard violation of a documented standard)
Spec (3 findings, all P3)
Full reports are in What I fixed
Unaddressed findingsStandards
Spec
Coverage
Validation
The
The extra-command list was empty, so there was nothing else to run. SecurityNo unaddressed introduced findings. Delivery failedpull request changed during Review run |
…home/jacob/repos/thirdshift-issue-2016 on expected Issue branch issue-2016: cannot inspect every registration in /home/jacob/repos/thirdshift/.git/worktrees; checkout path and head unknown) 2026-11-11T16:17:11Z, host stephens. Uncommitted work at the time of failure is included in this commit.
…hift into issue-2016 # Conflicts: # scripts/release.sh
2026-11-11T18:05:32Z, host lima-thirdshift. Uncommitted work at the time of failure is included in this commit.
Summary
Release PRs could wait indefinitely on missing workflows or a superseded head. Observe the captured PR throughout CI and reuse the existing Fix run for bounded recovery.
Cap external head changes at five and refuse changed PR identity, state, branches, origin, version or extra source content before tagging. Persist the release notes' content base across interrupted runs, refresh legacy notes, and preserve repaired merge-head recovery for failed unpublished tags. Published releases remain immutable. Ctrl-C during Fix startup prints recovery commands; a failed post-publication merge explains marking a draft PR ready.
Closes #2016
Evidence
Execution evidence
acb42c1f90c8c637b7295d8ab0d321d6fb1097d1, with the branch's regression fixtures copied into the detached checkout,cargo test --test release checks::a_conflict_without_workflows_runs_one_targeted_fix_and_releases_the_repaired_head -- --exact --nocapturefailed:release fixture exceeded 120s, printingwaiting for CI on …/pull/4;0 passed; 1 failed. The fixture establishes real competing Cargo version bumps and verifies their merge conflict.After: The same regression on the issue branch passed:
1 passed; 0 failed, releasing the repaired head through the fake publication workflow. A separate sourced merge-base probe observed 26 empty workflow reads until its three-second deadline.cargo test --test release checks::a_signal_interrupted_fix_reports_recovery_without_tagging -- --exact --nocapturefailed: signal termination producedstatus.code() == Noneand omitted recovery instructions. The reviewer's real-Cargo startup reproduction also failed with Bash exit-2.After: The same command passed:
1 passed; 0 failed; the release reports its PR/head and recovery commands, with no tag pushed.cargo test --test release checks::a_published_draft_pr_explains_how_to_finish_merging_without_moving_the_tag -- --exact --nocapturefailed on missing draft/ready guidance after publication.After: The same command passed:
1 passed; 0 failed; the published tag stays fixed and the PR remains open withgh pr readyguidance.cargo test --test release checks:: -- --test-threads=3: 22 passed, including identity mutations, extra-content refusal, head churn, missing-run expiry, Fix failure, Experiment refresh and interrupted publication recovery.scripts/affected-tests mainpassed all 68 site tests (152.80s), then stopped on unchangeddismiss::single_kind_dismissal_files_keep_their_kind_when_another_is_added: 617 passed, 1 failed, 97 skipped; the remaining tests were not run. It expected a dismissible row but observed Working.cargo test --test dismiss single_kind_dismissal_files_keep_their_kind_when_another_is_added -- --exact --nocapturethen passed: 1 passed; 0 failed. No dismissal code was changed.cargo test --test release -- --test-threads=3: 131 passed, 2 fixture entry points ignored atfb5071d5. Repeated after the main reconciliation at6d0153ea: 131 passed, 0 failed, 2 ignored (279.48s).python3 -m unittest discover -s scripts -p test_generate_release.py: 3 passed.npm run docs:check --prefix sitepassed after the final main merge.6d0153eapassed. The current head is25d92bc3: a main reconciliation followed by an empty failure-marker commit after the previous run encountered a draft PR. Current-head CI passed, including the full Rust suite, formatting, clippy, site and Console checks. Both musl artifact builds also passed on25d92bc3. Successful exact-head CI is reused for full-suite validation underdocs/testing.md.cargo fmt --check,bash -n scripts/release.shandgit diff --checkpassed.Test seams: the real release CLI, Git refs, PR/workflow observations through fake GitHub, and targeted Fix/Experiment/summary commands through fake Cargo/Harness adapters. Fixture children have bounded lifetimes; tests launch no real agents or releases.
Visual evidence
Release documentation at matching viewports with the release section open. Before is the supplied merge base; After is the reconciled branch. Captures contain no personal data.
Release manual, 1440×900:
Release manual, 390×844:
Homepage, 1440×900:
Homepage, 390×844:
How it works, 1440×900:
How it works, 390×844:
Architecture, 1440×900:
Architecture, 390×844:
Review coverage
Standards: 2 P3 findings, both addressed by sharing the Experiment Cargo stand-in and the existing child-lifetime runner. Spec: 2 P2 findings, both reproduced and fixed with retained regressions for signal interruption and published draft recovery.
Both reviewers read all nine changed files, including generated
site/docs/index.html, and reviewed the later draft-recovery additions throughfb5071d5. Generated exclusions: none. Changed files left unread: none. Final reports andsummary.json({"standards":2,"spec":2}) are retained with the Session trace.The final upstream reconciliation
6d0153eaexactly matchesgit merge-tree --write-tree fb5071d5 b02e7ae2(treeb113e2791afee887747ac6fc3c6e3635786317d4); the PR-owned diff still contains the same nine reviewed files. The earlier parallel review's S1, S7 and S8 and P1 are also addressed. Its remaining declined judgements are preserved below.Unaddressed findings
The current review's two Standards and two Spec findings are all fixed. The earlier parallel review left these judgements declined:
Standards
release_blockedfor recoverable blockages andrelease_stoppedfor identity/origin/release-boundary changes. The comment atscripts/release.sh:720explicitly defines why the latter offers no Fix run.write_summaryintentionally usesgit merge-base "$head" origin/main(scripts/release.sh:523) for a new re-cut bump, including while the previous PR is still recorded as MERGED.release_content_baseuses$merge^1to validate the old merged PR.recovery::an_old_merged_bump_can_be_recut_with_a_new_bump_prexercises this distinction. Within the open-PR wait, the expressions agree.scripts/release.sh:634and:655.checks::an_external_head_change_during_a_green_read_is_adopted_without_a_fixexercises the race these guards close. The two recovery messages deliberately offer different actions:release_blockedoffers a targeted Fix;release_stoppedasks for inspection.fix_attempted=1(scripts/release.sh:706) and five-update cap (:607) own invocation-wide budgets. The bounded-repeat and head-churn regressions exercise those budgets; a larger shell-state refactor is outside this bug fix.scripts/release.sh:736handles both real GitHub and the fake adapter, whose jq boolean output is Python-styleTrue.a_draft_bump_pr_after_publication_names_the_ready_steppasses through this check.Spec
release_notes_refresh=1(scripts/release.sh:567) conservatively regenerates it.checks::an_unmarked_legacy_pr_repaired_before_resume_refreshes_its_notesexercises the stale-notes case, and the manual documents the one-time refresh.gh pr readyearlier. Mergeability's clock starts only after all workflows complete (settling=${settling:-$SECONDS},scripts/release.sh:667); it places no deadline on queued/running CI.checks::green_ci_with_mergeability_stuck_unknown_stops_instead_of_waiting_foreverandchecks::pending_and_healthy_ci_never_start_a_fix_even_after_startup_graceexercise both sides.These are implementation judgements supported by the current code and regressions; none is deferred to a Spec or Day shift decision.
Security review outcome
No unaddressed introduced findings.
Takeover verification
Reviewed head
25d92bc3against pinned main4a301fab. The failure-marker commit changes no files. Marked the PR ready after review; no code changes were necessary.CARGO_TARGET_DIR=/home/jacob/repos/thirdshift/target cargo test --test release checks:: -- --test-threads=3: 23 passed, 0 failed (71.94s after compilation).python3 -m unittest discover -s scripts -p test_generate_release.py: 3 passed.npm run docs:check --prefix site,bash -n scripts/release.sh, andgit diff --check origin/main...HEAD: passed.Standards
No actionable findings. The final nine-file change follows the documented standards, uses the existing fake adapters, and bounds fixture children. Generated manual consistency was checked with
docs:check. 0 findings; no blocker.Spec
No findings against issue #2016. The final change covers bounded targeted Fix recovery, current-head validation, startup grace, notes and requested Experiment refresh, interrupted/draft recovery, and publication safeguards. 0 findings; no blocker.
Merge Danger
Door: two-way
The script changes can be reverted. Publication retains the existing immutable-release and publication-before-merge safeguards.
Blast Radius: releases
Maintainer release orchestration and its documentation/fixtures. One automatic targeted Fix run can consume agent time when a release PR has a conflict or completed failing CI.